package com.baiduspring.web.upload;

import com.baiduspring.config.UploadConfig;
import com.baiduspring.dao.entity.User;
import com.baiduspring.utils.string.StringUtils;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

@RestController
@RequestMapping(value = "/ueditor")
@Scope(value = "prototype")
@Slf4j
public class UeditorController {
    @Resource
    private UploadConfig uploadConfig;

    @RequestMapping(value = "/markdown/upload")
    public String markdownUpload(@RequestParam(value = "editormd-image-file", required = false) MultipartFile upfile, HttpServletRequest request) {
        String original = upfile.getOriginalFilename();
        String type = StringUtils.fileExtensionName(org.springframework.util.StringUtils.isEmpty(original) ? ".png" : original);

        User user = (User) request.getSession().getAttribute("user");
        String basePath = "/files/" + user.getAccount() + "/" + type;

        File file = new File(uploadConfig.getRootPath() + basePath);
        if (!file.exists()) {
            if (!file.mkdirs()) {
                if (file.mkdirs()) {
                    log.info("文件夹：" + basePath + "创建成功");
                }
            }
        }

        String fileName = UUID.randomUUID().toString() + type;
        File dest = new File(file, fileName);

        try {
            upfile.transferTo(dest);
        } catch (IOException e) {
            log.error("错误：", e);
            return this.respUploadStatus(0, "图片上传失败", "");
        } catch (IllegalStateException e) {
            log.error("错误：", e);
            return this.respUploadStatus(0, "图片上传失败", "");
        }

        return this.respUploadStatus(1, "图片上传成功", uploadConfig.getDomain() + ":" + uploadConfig.getPort() + basePath + "/" + fileName);
    }

    @RequestMapping("/demo")
    public Map<String, Object> demo(@RequestParam(value = "editormd-image-file", required = false) MultipartFile file, HttpServletRequest request) {
        Map<String, Object> resultMap = Maps.newHashMap();
        String realPath = request.getRealPath("/") + "assets/upload/";
        String fileName = file.getOriginalFilename();
        File targetFile = new File(realPath, fileName);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        } //保存
        try {
            file.transferTo(targetFile);
            resultMap.put("success", 1);
            resultMap.put("message", "上传成功！");
            resultMap.put("url", request.getContextPath() + "/assets/upload/" + fileName);
        } catch (Exception e) {
            resultMap.put("success", 0);
            resultMap.put("message", "上传失败！");
            e.printStackTrace();
        }
        return resultMap;
    }


    private String respUploadStatus(Integer success, String message, String url) {
        /*{
            success : 0 | 1,           // 0 表示上传失败，1 表示上传成功
                    message : "提示的信息，上传成功或上传失败及错误信息等。",
                client_id     : "图片地址"        // 上传成功时才返回
        }*/
        StringBuilder builder = new StringBuilder();
        builder.append("{")
                .append("\"success\" : ").append(success).append(",")
                .append("\"message\" : \"").append(message).append("\",")
                .append("\"url\" : \"").append(url).append("\"")
                .append("}");
        return builder.toString();
    }

    @RequestMapping(value = "/layupload")
    public String layUpload(MultipartFile file, HttpServletRequest request) {
        if (Objects.isNull(file)) {
            return this.respResult("SUCCESS", null, null, null, null, 0L);
        }

        log.info("upfile.getName(): {} ", file.getName());
        log.info("upfile.getSize(): {} ", file.getSize());
        log.info("upfile.getOriginalFilename(): {} ", file.getOriginalFilename());
        log.info("file(\"/\"){} ", new File("/"));
        log.info("request.getServletContext().getRealPath(\"/\") ", request.getServletContext().getRealPath("/"));

        String original = file.getOriginalFilename();
        String type = StringUtils.fileExtensionName(org.springframework.util.StringUtils.isEmpty(original) ? ".png" : original);

        User user = (User) request.getSession().getAttribute("user");
        String basePath = "/files/" + user.getAccount() + "/" + type;

        File ufile = new File(uploadConfig.getRootPath() + basePath);
        if (!ufile.exists()) {
            if (!ufile.mkdirs()) {
                log.info("文件夹：" + basePath + "创建成功");
            }
        }

        String fileName = UUID.randomUUID().toString() + type;
        File dest = new File(ufile, fileName);

        try {
            file.transferTo(dest);
        } catch (IOException e) {
            log.error("错误：", e);
            return this.respResult("FAIL", null, fileName, original, type, file.getSize());
        }

        return this.respResult("SUCCESS", uploadConfig.getDomain() + ":" + uploadConfig.getPort() + basePath + "/" + fileName, fileName, original, type, file.getSize());
    }

    @RequestMapping(value = "/upload")
    public String upload(String action, MultipartFile upfile, HttpServletRequest request) {
        String config = "config";
        if (action.equalsIgnoreCase(config)) {
            return this.config();
        }

        if (Objects.isNull(upfile)) {
            return this.respResult("SUCCESS", null, null, null, null, 0L);
        }

        log.info("upfile.getName(): {} ", upfile.getName());
        log.info("upfile.getSize(): {} ", upfile.getSize());
        log.info("upfile.getOriginalFilename(): {} ", upfile.getOriginalFilename());
        log.info("file(\"/\"){} ", new File("/"));
        log.info("request.getServletContext().getRealPath(\"/\") ", request.getServletContext().getRealPath("/"));

        String original = upfile.getOriginalFilename();
        String type = StringUtils.fileExtensionName(org.springframework.util.StringUtils.isEmpty(original) ? ".png" : original);

        User user = (User) request.getSession().getAttribute("user");
        String basePath = "/files/" + user.getAccount() + "/" + type;

        File file = new File(uploadConfig.getRootPath() + basePath);
        if (!file.exists()) {
            if (!file.mkdirs()) {
                log.info("文件夹：" + basePath + "创建成功");
            }
        }

        String fileName = UUID.randomUUID().toString() + type;
        File dest = new File(file, fileName);

        try {
            upfile.transferTo(dest);
        } catch (IOException e) {
            log.error("错误：", e);
            return this.respResult("FAIL", null, fileName, original, type, upfile.getSize());
        } catch (IllegalStateException e) {
            log.error("错误：", e);
            return this.respResult("FAIL", null, fileName, original, type, upfile.getSize());
        }

        return this.respResult("SUCCESS", uploadConfig.getDomain() + ":" + uploadConfig.getPort() + basePath + "/" + fileName, fileName, original, type, upfile.getSize());
    }

    private String respResult(String state, String url, String title, String original, String type, Long size) {
        return "{\"state\":\"" + state + "\",\"url\":\"" + url + "\",\"title\":\"" + title + "\",\"original\":\"" + original + "\",\"type\":\"" + type + "\",\"size\":" + size + "}";
    }

    private String config() {
        return "/* 前后端通信相关的配置,注释只允许使用多行方式 */\n" +
                "{\n" +
                "    /* 上传图片配置项 */\n" +
                "    \"imageActionName\": \"uploadimage\", /* 执行上传图片的action名称 */\n" +
                "    \"imageFieldName\": \"upfile\", /* 提交的图片表单名称 */\n" +
                "    \"imageMaxSize\": 2048000, /* 上传大小限制，单位B */\n" +
                "    \"imageAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 上传图片格式显示 */\n" +
                "    \"imageCompressEnable\": true, /* 是否压缩图片,默认是true */\n" +
                "    \"imageCompressBorder\": 1600, /* 图片压缩最长边限制 */\n" +
                "    \"imageInsertAlign\": \"none\", /* 插入的图片浮动方式 */\n" +
                "    \"imageUrlPrefix\": \"\", /* 图片访问路径前缀 */\n" +
                "    \"imagePathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n" +
                "                                /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */\n" +
                "                                /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */\n" +
                "                                /* {time} 会替换成时间戳 */\n" +
                "                                /* {yyyy} 会替换成四位年份 */\n" +
                "                                /* {yy} 会替换成两位年份 */\n" +
                "                                /* {mm} 会替换成两位月份 */\n" +
                "                                /* {dd} 会替换成两位日期 */\n" +
                "                                /* {hh} 会替换成两位小时 */\n" +
                "                                /* {ii} 会替换成两位分钟 */\n" +
                "                                /* {ss} 会替换成两位秒 */\n" +
                "                                /* 非法字符 \\ : * ? \" < > | */\n" +
                "                                /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */\n" +
                "\n" +
                "    /* 涂鸦图片上传配置项 */\n" +
                "    \"scrawlActionName\": \"uploadscrawl\", /* 执行上传涂鸦的action名称 */\n" +
                "    \"scrawlFieldName\": \"upfile\", /* 提交的图片表单名称 */\n" +
                "    \"scrawlPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n" +
                "    \"scrawlMaxSize\": 2048000, /* 上传大小限制，单位B */\n" +
                "    \"scrawlUrlPrefix\": \"\", /* 图片访问路径前缀 */\n" +
                "    \"scrawlInsertAlign\": \"none\",\n" +
                "\n" +
                "    /* 截图工具上传 */\n" +
                "    \"snapscreenActionName\": \"uploadimage\", /* 执行上传截图的action名称 */\n" +
                "    \"snapscreenPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n" +
                "    \"snapscreenUrlPrefix\": \"\", /* 图片访问路径前缀 */\n" +
                "    \"snapscreenInsertAlign\": \"none\", /* 插入的图片浮动方式 */\n" +
                "\n" +
                "    /* 抓取远程图片配置 */\n" +
                "    \"catcherLocalDomain\": [\"127.0.0.1\", \"localhost\", \"img.baidu.com\"],\n" +
                "    \"catcherActionName\": \"catchimage\", /* 执行抓取远程图片的action名称 */\n" +
                "    \"catcherFieldName\": \"source\", /* 提交的图片列表表单名称 */\n" +
                "    \"catcherPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n" +
                "    \"catcherUrlPrefix\": \"\", /* 图片访问路径前缀 */\n" +
                "    \"catcherMaxSize\": 2048000, /* 上传大小限制，单位B */\n" +
                "    \"catcherAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 抓取图片格式显示 */\n" +
                "\n" +
                "    /* 上传视频配置 */\n" +
                "    \"videoActionName\": \"uploadvideo\", /* 执行上传视频的action名称 */\n" +
                "    \"videoFieldName\": \"upfile\", /* 提交的视频表单名称 */\n" +
                "    \"videoPathFormat\": \"/ueditor/jsp/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n" +
                "    \"videoUrlPrefix\": \"\", /* 视频访问路径前缀 */\n" +
                "    \"videoMaxSize\": 102400000, /* 上传大小限制，单位B，默认100MB */\n" +
                "    \"videoAllowFiles\": [\n" +
                "        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
                "        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\"], /* 上传视频格式显示 */\n" +
                "\n" +
                "    /* 上传文件配置 */\n" +
                "    \"fileActionName\": \"uploadfile\", /* controller里,执行上传视频的action名称 */\n" +
                "    \"fileFieldName\": \"upfile\", /* 提交的文件表单名称 */\n" +
                "    \"filePathFormat\": \"/ueditor/jsp/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n" +
                "    \"fileUrlPrefix\": \"\", /* 文件访问路径前缀 */\n" +
                "    \"fileMaxSize\": 51200000, /* 上传大小限制，单位B，默认50MB */\n" +
                "    \"fileAllowFiles\": [\n" +
                "        \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" +
                "        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
                "        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" +
                "        \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" +
                "        \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" +
                "    ], /* 上传文件格式显示 */\n" +
                "\n" +
                "    /* 列出指定目录下的图片 */\n" +
                "    \"imageManagerActionName\": \"listimage\", /* 执行图片管理的action名称 */\n" +
                "    \"imageManagerListPath\": \"/ueditor/jsp/upload/image/\", /* 指定要列出图片的目录 */\n" +
                "    \"imageManagerListSize\": 20, /* 每次列出文件数量 */\n" +
                "    \"imageManagerUrlPrefix\": \"\", /* 图片访问路径前缀 */\n" +
                "    \"imageManagerInsertAlign\": \"none\", /* 插入的图片浮动方式 */\n" +
                "    \"imageManagerAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 列出的文件类型 */\n" +
                "\n" +
                "    /* 列出指定目录下的文件 */\n" +
                "    \"fileManagerActionName\": \"listfile\", /* 执行文件管理的action名称 */\n" +
                "    \"fileManagerListPath\": \"/ueditor/jsp/upload/file/\", /* 指定要列出文件的目录 */\n" +
                "    \"fileManagerUrlPrefix\": \"\", /* 文件访问路径前缀 */\n" +
                "    \"fileManagerListSize\": 20, /* 每次列出文件数量 */\n" +
                "    \"fileManagerAllowFiles\": [\n" +
                "        \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" +
                "        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
                "        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" +
                "        \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" +
                "        \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" +
                "    ] /* 列出的文件类型 */\n" +
                "\n" +
                "}";
    }

}
